W ramach niniejszego zadania pracowano na danych pochodzących z trzech elektrowni słonecznych we Włoszech. Celem pracy była próba przewidzenia energii wytwarzanej przez panele fotowoltaiczne w oparciu o historyczne dane. W pierwszym kroku przeanalizowano posiadany zbiór danych pod kątem występowania tzw. missing values. Problemem okazało się rozróżnianie wartości prawidłowych od wartości brakujących, ponieważ te drugie reprezentowane były przez wartość zero, która w innym przypadku była wartością prawidłową. Na podstawie ilości wytworzonej energii wyodrębniono przypadki brakującej wartości promieniowania słonecznego irradiamento, a następnie oszacowano dla nich możliwą wartość w oparciu o pomiary innych czujników wykonane o tej samej godzinie, tego samego dnia. Następnie sprawdzono korelacje występujące między poszczególnymi zmiennymi analizowanego zbioru danych. Zgodnie z przypuszczeniami, okazało się, że największy wpływ na ilość wytwarzanej energii ma między innymi ilość promieniowania słonecznego oraz wilgotność powietrza. Atrybuty te wykorzystano do stworzenia modelu regresji, wykorzystując metodę lm czyli regresję liniową.
Przed przystąpieniem do analizy posiadanych danych, przygotowano środowisko niezbędne do pracy. Przygotowanie to polegało między innymi na załadowaniu niezbędnych bibliotek oraz zapewnieniu powtarzalności wyników.
Podczas realizacji zadania wykorzystano następujące biblioteki:
library(dplyr)
library(knitr)
library(caret)
library(plotly)
library(ggplot2)
library(reshape2)
Powtarzalność wyników zapewniono ustawiając stałe ziarno:
set.seed(3)
Po wczytaniu danych poddano je wstępnej obróbce. Zajęto się analizą a następnie obróbką brakujących danych.
Dane wczytano do zmiennej raw_df wykorzystując funkcję read.csv():
raw_df <- read.csv("elektrownie.csv")
W związku z tym, że przetwarzane dane pochodzą z czujników, które mogły ulegać awarii, bądź były wyłączone przez pewien czas, w danych tych możliwe jest występowanie wartości pustych, nieokreślonych czy zerowych. Z tego powodu, w miejscu tym dokonano przeglądu analizowanych danych i poddano je obróbce. Ponieważ w posiadanym zbiorze, wartości brakujące reprezentowane są przez wartość 0, ciężko jest ocenić, które z wystąpnień tej wartości są wartościami prawidłowymi, a które brakującymi. Udało się to dla atrybutu irradiamento. Jeśli wytworzono energię, tzn. kwh > 0 a wartość irradiamento jest równa 0, oznacza to, że jest to wartość brakująca, ponieważ w przeciwnym razie panel nie wytworzyłby energii. Znalezione w ten sposób wartości puste zastąpiono średnią wartością promieniowania o danej godzinie w danym dniu.
# skopiowanie danych
my_df <- raw_df
# wyodrebnienie danych zawierajacych brakujace wartosci promieniowania
missing_irradiamento <- my_df %>% filter(irradiamento == 0, kwh > 0)
# wyznaczenie pozostalej czesci zbioru danych
occurring_irradiamento <- setdiff(my_df, missing_irradiamento)
# zamiana wartosci brakujacych na oszacowana wartosc sredniej
missing_irradiamento$irradiamento <- apply(missing_irradiamento, 1, function (row) {
similar_data <- my_df %>%
filter(
data == row[["data"]]
)
row[["irradiamento"]] <- mean(similar_data[["irradiamento"]])
})
# sklejenie fragmentow zbioru z powrotem w jeden
my_df <- rbind(occurring_irradiamento, missing_irradiamento)
Po wstępnym przygotowaniu danych przystąpiono do ich analizy. Przebadano między innymi wartości przyjmowane przez poszczególne atrybuty jak również korelację między poszczególnymi zmiennymi. Przygotowano również wykresy zmiany wytwarzanej energii w czasie i przestrzeni.
Analizowany zbiór danych zawiera informacje na temat energii, wytwarzanej przez panele fotowoltaiczne. Dane te pochodzą z trzech elektrowni słonecznych we Włoszech. Zbiór danych składa się z 235790 wierszy. Każdy z nich zawiera średnie wartości pomiarów wyznaczane co godzinę dla pojedynczego czujnika. Poza wartościami wytwarzanej energii i znacznikami czasowymi, dla każdego z czujników przechowywane są dane geograficzne i pogodowe. W sumie każdy z wierszy opisany jest przez 51 atrybutów. Są to:
## [1] "id" "idsito" "idmodel"
## [4] "idbrand" "lat" "lon"
## [7] "ageinmonths" "anno" "day"
## [10] "ora" "data" "temperatura_ambiente"
## [13] "irradiamento" "pressure" "windspeed"
## [16] "humidity" "icon" "dewpoint"
## [19] "windbearing" "cloudcover" "tempi"
## [22] "irri" "pressurei" "windspeedi"
## [25] "humidityi" "dewpointi" "windbearingi"
## [28] "cloudcoveri" "dist" "altitude"
## [31] "azimuth" "altitudei" "azimuthi"
## [34] "pcnm1" "pcnm2" "pcnm3"
## [37] "pcnm4" "pcnm5" "pcnm6"
## [40] "pcnm7" "pcnm8" "pcnm9"
## [43] "pcnm10" "pcnm11" "pcnm12"
## [46] "pcnm13" "pcnm14" "pcnm15"
## [49] "irr_pvgis_mod" "irri_pvgis_mod" "kwh"
Wszystkie dane znajdujące się w analizowanym zbiorze, za wyjątkiem identyfikatora pomiaru (id), roku (anno) oraz pełnej daty (data), są znormalizowane. Z tego powodu ich analiza jest utrudniona. W tabeli poniżej przedstawiono wartości podstawowych statystyk dla wybranych atrybutów omawianego zbioru. Statystyki te to: wartość minimalna, wartość maksymalna, średnia arytmetyczna, mediana, pierwszy i trzeci kwartyl, a także liczba unikalnych wartości.
| Wartość najmniejsza | Pierwszy kwartyl | Mediana | Średnia arytmetyczna | Trzeci kwartyl | Wartość największa | Liczba unikalnych wartości | |
|---|---|---|---|---|---|---|---|
| temperatura_ambiente | 0.045 | 0.212 | 0.348 | 0.3734429 | 0.530 | 0.818 | 52 |
| irradiamento | 0.000 | 0.000 | 0.041 | 0.1116034 | 0.209 | 0.710 | 3198 |
| pressure | 0.000 | 0.748 | 0.753 | 0.6504251 | 0.755 | 0.769 | 41 |
| windspeed | 0.000 | 0.042 | 0.066 | 0.0762241 | 0.102 | 0.696 | 367 |
| humidity | 0.160 | 0.540 | 0.700 | 0.6843925 | 0.840 | 1.000 | 85 |
| dewpoint | 0.139 | 0.535 | 0.619 | 0.6055304 | 0.683 | 0.865 | 634 |
| windbearing | 0.000 | 0.300 | 0.478 | 0.4512351 | 0.660 | 0.769 | 360 |
| cloudcover | 0.000 | 0.230 | 0.310 | 0.3590429 | 0.510 | 1.000 | 101 |
| altitude | 0.111 | 0.419 | 0.564 | 0.5463627 | 0.681 | 0.884 | 773 |
| azimuth | 0.128 | 0.295 | 0.425 | 0.4545834 | 0.635 | 0.818 | 689 |
| kwh | 0.000 | 0.000 | 0.049 | 0.1687714 | 0.332 | 1.000 | 864 |
Podczas wyznaczania macierzy korelacji pominięto atrybut data, ponieważ jest on typu Factor, natomiast funkcja cor() wymaga danych numerycznych.
# wyznaczenie macierzy korelacji (pominiecie atrybutu 11 - data)
cor_matrix <- cor(my_df[, -11])
# przeksztalcenie macierzy korelacji
cor_df <- melt(cor_matrix)
Jak widać na poniższym wykresie, ilość wytworzonej energii kwh jest znacząco skorelowana między innymi z promieniowaniem irradiamento (pozytywnie) oraz z wilgotnością powietrza humidity (negatywnie). Współczynniki tych korelacji wynoszą odpowiednio: 0.8757128 i -0.5319679. Oczywistym jest fakt, że nie wszystkie znalezione zależności mają odzwierciedlenie w rzeczywistości, np. wartość idsito (identyfikator czujnika) nie zależy od szerokości geograficznej lat czy ciśnienia atmosferycznego pressure jak mogłyby wskazywać współczynniki korelacji między tymi zmiennymi. Podobnie nie należy szukać zależności między szerokością geograficzną lat a długością geograficzną lon. Warto zwrócić jednak uwagę np. na korelację pomiędzy godziną (ora) a azymutem (azimuth), który określa położenie Słońca na niebie (kierunek geograficzny wyrażony w mierze kątowej). W godzinach porannych Słońce znajduje się po wschodniej stronie nieba, natomiast wieczorem po stronie zachodniej.
Poniższy wykres przedstawia zmianę wytwarzanej energii w czasie i przestrzeni. Aby pokazać/ukryć serie danych należy kliknąć na żądanej pozycji legendy (każda seria danych to dane z jednego czujnika). Korzystając z suwaka na dole możliwa jest zmiana zakresu czasu.